package com.pipi.biyesheji.service.impl;


import com.pipi.biyesheji.dao.manager.RoleManager;
import com.pipi.biyesheji.dao.manager.UserRoleManager;
import com.pipi.biyesheji.dao.model.RoleDO;
import com.pipi.biyesheji.dao.model.UserRoleDO;
import com.pipi.biyesheji.dao.query.RoleQuery;
import com.pipi.biyesheji.dao.query.UserRoleQuery;
import com.pipi.biyesheji.pojo.Role;
import com.pipi.biyesheji.pojo.User;
import com.pipi.biyesheji.service.RoleService;
import com.pipi.biyesheji.service.UserService;
import com.pipi.biyesheji.util.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author pipi
 */
@Service
public class RoleServiceImpl implements RoleService {

    @Autowired
    private RoleManager roleManager;
    @Autowired
    private UserRoleManager userRoleManager;
    @Autowired
    UserService userService;

    @Override  //name的所有角色
    public Set<String> listRoleNames(String userName) {
        Set<String> result = new HashSet<>();
        //查出管理员相应的角色
        List<Role> roles = listRoles(userName);
        //把每个角色名放到set集合中
        for (Role role : roles) {
            result.add(role.getName());
        }
        return result;
    }

    @Override  //查出管理员相应的角色
    public List<Role> listRoles(String userName) {
        List<Role> roles = new ArrayList<>();
        //通过name获得user实体
        User user = userService.getByName(userName);
        if(null==user) {
            return roles;
        }
        //调用下面的方法
        roles = listRoles(user);
        return roles;
    }

    @Override  //查出管理员相应的角色
    public List<Role> listRoles(User user) {
        List<Role> roles = new ArrayList<>();
        //通过管理员id获取管理员的角色
        UserRoleQuery userRoleQuery = new UserRoleQuery();
        userRoleQuery.createCriteria().andUidEqualTo(user.getId());
        List<UserRoleDO> userRoleDOS = userRoleManager.selectByQuery(userRoleQuery);
        //关联查询  查出用户id对应的角色id的记录
        List<Long> rids = userRoleDOS.stream().map(UserRoleDO::getRid).collect(Collectors.toList());
        RoleQuery roleQuery = new RoleQuery();
        roleQuery.createCriteria().andIdIn(rids);
        List<RoleDO> roleDOS = roleManager.selectByQuery(roleQuery);
        Map<Long, Role> roleMap = roleDOS.stream().collect(Collectors.toMap(RoleDO::getId, this::buildRole));

        //通过关联查询 ，查出表Role的给出指定主键id的记录
        for (UserRoleDO userRoleDO : userRoleDOS){
            Long rid = userRoleDO.getRid();
            roles.add(roleMap.get(rid));
        }
        return roles;
    }

    @Override
    public List<Role> list() {
        RoleQuery roleQuery = new RoleQuery();
        roleQuery.setOrderByClause("id desc");
        List<RoleDO> roleDOS = roleManager.selectByQuery(roleQuery);
        return buildRoles(roleDOS);
    }

    @Override
    public void add(Role role) {
        RoleDO roleDO = BeanUtils.createCloneBean(role, RoleDO.class);
        roleManager.insertSelective(roleDO);
    }

    @Override
    public void delete(Long id) {
        roleManager.deleteByPrimaryKey(id);
    }

    @Override
    public Role get(Long id) {
        RoleDO roleDO = roleManager.selectByPrimaryKey(id);
        return buildRole(roleDO);
    }

    @Override
    public void update(Role role) {
        RoleDO roleDO = BeanUtils.createCloneBean(role, RoleDO.class);
        roleManager.updateByPrimaryKeySelective(roleDO);
    }

    @Override
    public Role getRoleByUserId(Long userId) {
        UserRoleQuery userRoleQuery = new UserRoleQuery();
        userRoleQuery.createCriteria().andUidEqualTo(userId);
        List<UserRoleDO> userRoleDOS = userRoleManager.selectByQuery(userRoleQuery);
        Long rid = userRoleDOS.get(0).getRid();
        RoleDO roleDO = roleManager.selectByPrimaryKey(rid);
        return buildRole(roleDO);
    }

    private List<Role> buildRoles(List<RoleDO> roleDOList) {
        return roleDOList.stream().map(this::buildRole).collect(Collectors.toList());
    }

    private Role buildRole(RoleDO roleDO) {
        if (Objects.isNull(roleDO)) {
            return null;
        }
        return BeanUtils.createCloneBean(roleDO, Role.class);
    }
}
